#include "kernel/shapeedit/shapeedit.h"
#include <QTextBlock>
#include <QPainter>
ShapeEdit::ShapeEdit(QWidget* parent /*= nullptr*/):QPlainTextEdit(parent)
{
	lineNumberArea = new LineNumberArea(this);
	connect(this, &ShapeEdit::blockCountChanged, this, &ShapeEdit::updateLineNumberAreaWidth);
	connect(this, &ShapeEdit::updateRequest, this, &ShapeEdit::updateLineNumberArea);
	connect(this, &ShapeEdit::cursorPositionChanged, this, &ShapeEdit::highlightCurrentLine);

	updateLineNumberAreaWidth(0);
	highlightCurrentLine();

}

ShapeEdit::~ShapeEdit()
{

}

void ShapeEdit::lineNumberAreaPaintEvent(QPaintEvent* event)
{
	QPainter painter(lineNumberArea);
	painter.fillRect(event->rect(), Qt::lightGray);
	QTextBlock block = firstVisibleBlock();
	int blockNumber = block.blockNumber();
	int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top());
	int bottom = top + qRound(blockBoundingRect(block).height());
	//![extraAreaPaintEvent_1]

	//![extraAreaPaintEvent_2]
	while (block.isValid() && top <= event->rect().bottom()) {
		if (block.isVisible() && bottom >= event->rect().top()) {
			QString number = QString::number(blockNumber + 1);
			painter.setPen(Qt::black);
			painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
				Qt::AlignRight, number);
		}

		block = block.next();
		top = bottom;
		bottom = top + qRound(blockBoundingRect(block).height());
		++blockNumber;
	}
}

int ShapeEdit::lineNumberAreaWidth()
{
	int digts = 1;
	int max = qMax(1, blockCount());
	while (max >= 10) {
		max /= 10;
		++digts;
	}
	int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9'))*digts;
	return space;
}

void ShapeEdit::resizeEvent(QResizeEvent* event)
{
	QPlainTextEdit::resizeEvent(event);
	QRect cr = contentsRect();
	lineNumberArea->setGeometry(QRect(cr.left(),cr.top(),lineNumberAreaWidth(),cr.height()));

}

void ShapeEdit::updateLineNumberAreaWidth(int newBlockCount)
{
	setViewportMargins(lineNumberAreaWidth(),0,0,0);
}

void ShapeEdit::highlightCurrentLine()
{
	QList<QTextEdit::ExtraSelection> extraSelecttions;
	if (!isReadOnly()) {
		QTextEdit::ExtraSelection selection;
		QColor lineColor = QColor(Qt::blue).lighter(160);
		selection.format.setBackground(lineColor);
		selection.format.setProperty(QTextFormat::FullWidthSelection, true);
		selection.cursor = textCursor();
		selection.cursor.clearSelection();
		extraSelecttions.append(selection);
	}
	setExtraSelections(extraSelecttions);
}

void ShapeEdit::updateLineNumberArea(const QRect& rect, int dy)
{
	if (dy) 
	{
		lineNumberArea->scroll(0,dy);
	}
	else
	{
		lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
	}
	if (rect.contains(viewport()->rect()))
	{
		updateLineNumberAreaWidth(0);
	}
}

